package com.xin.vo
{
/**
 * @author daichangxin
 */
public class Vector2D
{
	private var _x:Number;
	private var _y:Number;
	public function Vector2D(x:Number, y:Number):void
	{
		_x = x;
		_y = y;
	}
	
	/**
	 * 将当前向量变成0向量
	 */
	public function zero():Vector2D
	{
		_x = 0;
		_y = 0;
		return this;
	}
	
	/**
	 * @return 向量的角度
	 */
	public function get angle():Number
	{
		return Math.atan2(_y, _x);
	}
	
	public function set angle(value:Number):void
	{
		var l:Number = length;
		_x = Math.cos(value) * l;
		_y = Math.sin(value) * l;
	}
	
	/**
	 * 设置向量大小
	 */
	public function set length(value:Number):void
	{
		var a:Number = angle;
		_x = Math.cos(a) * value;
		_y = Math.sin(a) * value;
	}
	public function get length():Number
	{
		return Math.sqrt(lengthSQ);
	}
	
	public function get lengthSQ():Number
	{
		return _x * _x + _y * _y;
	}
	
	/**
	 * 转化为单位向量
	 */
	public function normalize():Vector2D
	{
		var l:Number = length;
		if (l == 0)
		{
			_x = 1;
		}
		else
		{
			_x /= l;
			_y /= l;
		}
		return this;
	}
	
	/**
	 * 反转向量
	 */
	public function reverse():Vector2D
	{
		_x = -_x;
		_y = -_y;
		return this;
	}
	
	/**
	 * 判断是否是单位向量
	 */
	public function isNormalized():Boolean
	{
		return length == 1;
	}
	
	/**
	 * 乘以v2
	 */
	public function doProd(v2:Vector2D):Number
	{
		return _x * v2.x + _y * v2.y;
	}
	
	/**
	 * 判断两个向量是否垂直
	 */
	public function isCrossProd(v2:Vector2D):Boolean
	{
		return _x * v2.x - _y * v2.y == 0;
	}
	
	/**
	 * 计算两个向量夹角的弧度
	 */
	public static function getAngleBetween(v1:Vector2D, v2:Vector2D):Number
	{
		var v1clone:Vector2D = v1.clone().normalize();
		var v2clone:Vector2D = v2.clone().normalize();
		return Math.acos(v1clone.doProd(v2clone));
	}
	
	/**
	 * 返回与指定向量的距离
	 */
	public function distance(v2:Vector2D):Number
	{
		return Math.sqrt(distanceSQ(v2));
	}
	
	public function distanceSQ(v2:Vector2D):Number
	{
		var dx:Number = v2.x - _x;
		var dy:Number = v2.y - _y;
		return dx * dx + dy * dy;
	}
	
	/**
	 * 加上v2
	 */
	public function add(v2:Vector2D):Vector2D
	{
		return new Vector2D(_x + v2.x, _y + v2.y);
	}
	
	/**
	 * 减去v2
	 */
	public function subtract(v2:Vector2D):Vector2D
	{
		return new Vector2D(_x - v2.x, _y - v2.y);
	}
	
	/**
	 * 数与向量的乘积
	 */
	public function multiProd(value:Number):Vector2D
	{
		return new Vector2D(_x * value, _y * value);
	}
	
	public function clone():Vector2D
	{
		return new Vector2D(_x, _y);
	}
	
	/**
	 * 截取向量段
	 */
	public function truncate(value:Number):Vector2D
	{
		length = Math.max(value, length);
		return this;
	}
	
	public function set x(value:Number):void
	{
		_x = value;
	}
	public function get x():Number
	{
		return _x;
	}
	
	public function set y(value:Number):void
	{
		_y = value;
	}
	public function get y():Number
	{
		return _y;
	}
	
	public function toString():String
	{
		return "[Vector2D(x:" + _x + ", y:" + ")]";
	}
}
}
